using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace MatrixFramework.Core.Configuration;

/// <summary>
/// 配置管理器接口
/// </summary>
public interface IConfigurationManager
{
    /// <summary>
    /// 获取配置值
    /// </summary>
    /// <param name="key">配置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>配置值</returns>
    Task<string> GetValueAsync(string key, string? defaultValue = null, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取强类型配置值
    /// </summary>
    /// <typeparam name="T">配置类型</typeparam>
    /// <param name="key">配置键</param>
    /// <param name="defaultValue">默认值</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>配置值</returns>
    Task<T> GetValueAsync<T>(string key, T? defaultValue = default, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 设置配置值
    /// </summary>
    /// <param name="key">配置键</param>
    /// <param name="value">配置值</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="category">配置分类</param>
    /// <param name="description">配置描述</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task SetValueAsync(string key, string value, Guid? tenantId = null, string? category = null, string? description = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 设置强类型配置值
    /// </summary>
    /// <typeparam name="T">配置类型</typeparam>
    /// <param name="key">配置键</param>
    /// <param name="value">配置值</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="category">配置分类</param>
    /// <param name="description">配置描述</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task SetValueAsync<T>(string key, T value, Guid? tenantId = null, string? category = null, string? description = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 删除配置项
    /// </summary>
    /// <param name="key">配置键</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task RemoveAsync(string key, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取分类下的所有配置
    /// </summary>
    /// <param name="category">配置分类</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>配置项列表</returns>
    Task<Dictionary<string, string>> GetCategoryAsync(string category, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取租户的所有配置
    /// </summary>
    /// <param name="tenantId">租户ID</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>配置项列表</returns>
    Task<Dictionary<string, string>> GetTenantAsync(Guid tenantId, CancellationToken cancellationToken = default);

    /// <summary>
    /// 批量设置配置
    /// </summary>
    /// <param name="configItems">配置项字典</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="category">配置分类（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task SetBatchAsync(Dictionary<string, string> configItems, Guid? tenantId = null, string? category = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 刷新配置缓存
    /// </summary>
    /// <param name="key">配置键（可选，为空则刷新所有）</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>任务</returns>
    Task RefreshAsync(string? key = null, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 检查配置是否存在
    /// </summary>
    /// <param name="key">配置键</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>是否存在</returns>
    Task<bool> ExistsAsync(string key, Guid? tenantId = null, CancellationToken cancellationToken = default);

    /// <summary>
    /// 获取配置变更历史
    /// </summary>
    /// <param name="key">配置键</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="startTime">开始时间（可选）</param>
    /// <param name="endTime">结束时间（可选）</param>
    /// <param name="maxCount">最大数量</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>变更历史列表</returns>
    Task<List<ConfigurationChangeHistory>> GetHistoryAsync(string key, Guid? tenantId = null, DateTime? startTime = null, DateTime? endTime = null, int maxCount = 50, CancellationToken cancellationToken = default);

    /// <summary>
    /// 导出配置
    /// </summary>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="category">配置分类（可选）</param>
    /// <param name="format">导出格式</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>导出内容</returns>
    Task<string> ExportAsync(Guid? tenantId = null, string? category = null, ConfigurationExportFormat format = ConfigurationExportFormat.Json, CancellationToken cancellationToken = default);

    /// <summary>
    /// 导入配置
    /// </summary>
    /// <param name="content">配置内容</param>
    /// <param name="tenantId">租户ID（可选）</param>
    /// <param name="format">导入格式</param>
    /// <param name="overwrite">是否覆盖现有配置</param>
    /// <param name="cancellationToken">取消令牌</param>
    /// <returns>导入结果</returns>
    Task<ConfigurationImportResult> ImportAsync(string content, Guid? tenantId = null, ConfigurationExportFormat format = ConfigurationExportFormat.Json, bool overwrite = false, CancellationToken cancellationToken = default);
}

/// <summary>
/// 配置变更历史
/// </summary>
public class ConfigurationChangeHistory
{
    public Guid Id { get; set; }
    public string Key { get; set; } = string.Empty;
    public string OldValue { get; set; } = string.Empty;
    public string NewValue { get; set; } = string.Empty;
    public string Category { get; set; } = string.Empty;
    public Guid? TenantId { get; set; }
    public string ChangedBy { get; set; } = string.Empty;
    public DateTime ChangeTime { get; set; }
    public ConfigurationChangeType ChangeType { get; set; }
    public string Description { get; set; } = string.Empty;
}

/// <summary>
/// 配置变更类型
/// </summary>
public enum ConfigurationChangeType
{
    Created,
    Updated,
    Deleted,
    Imported,
    Exported
}

/// <summary>
/// 配置导出格式
/// </summary>
public enum ConfigurationExportFormat
{
    Json,
    Xml,
    Yaml,
    Properties
}

/// <summary>
/// 配置导入结果
/// </summary>
public class ConfigurationImportResult
{
    public int TotalCount { get; set; }
    public int SuccessCount { get; set; }
    public int FailureCount { get; set; }
    public int SkippedCount { get; set; }
    public IReadOnlyList<string> Errors { get; private set; } = new List<string>();
    public IReadOnlyList<string> Warnings { get; private set; } = new List<string>();
    public TimeSpan Duration { get; set; }
    public DateTime ImportTime { get; set; } = DateTime.UtcNow;

    /// <summary>
    /// 添加错误信息
    /// </summary>
    /// <param name="error">错误信息</param>
    public void AddError(string error)
    {
        if (string.IsNullOrEmpty(error)) return;

        var errors = new List<string>(Errors);
        errors.Add(error);
        Errors = errors.AsReadOnly();
    }

    /// <summary>
    /// 添加多个错误信息
    /// </summary>
    /// <param name="errors">错误信息列表</param>
    public void AddErrors(IEnumerable<string> errors)
    {
        if (errors == null) return;

        var errorList = new List<string>(Errors);
        errorList.AddRange(errors.Where(e => !string.IsNullOrEmpty(e)));
        Errors = errorList.AsReadOnly();
    }

    /// <summary>
    /// 添加警告信息
    /// </summary>
    /// <param name="warning">警告信息</param>
    public void AddWarning(string warning)
    {
        if (string.IsNullOrEmpty(warning)) return;

        var warnings = new List<string>(Warnings);
        warnings.Add(warning);
        Warnings = warnings.AsReadOnly();
    }

    /// <summary>
    /// 添加多个警告信息
    /// </summary>
    /// <param name="warnings">警告信息列表</param>
    public void AddWarnings(IEnumerable<string> warnings)
    {
        if (warnings == null) return;

        var warningList = new List<string>(Warnings);
        warningList.AddRange(warnings.Where(w => !string.IsNullOrEmpty(w)));
        Warnings = warningList.AsReadOnly();
    }
}